package com.heima.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.common.constant.MessageConstant;
import com.heima.common.context.BaseContext;
import com.heima.common.exception.BaseException;
import com.heima.common.result.PageResult;
import com.heima.mapper.*;
import com.heima.pojo.dto.NodePageDTO;
import com.heima.pojo.entity.*;
import com.heima.pojo.vo.NodeCollectVO;
import com.heima.pojo.vo.NodeDetailVO;
import com.heima.pojo.vo.RegionPageVO;
import com.heima.pojo.vo.tbNodePageVO;
import com.heima.service.NodeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 点位业务逻辑层实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor // 自动注入
public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements NodeService {

    private final NodeMapper nodeMapper;
    private final VendingMachineMapper vendingMachineMapper;
    private final RegionMapper regionMapper;
    private final BusinessMapper businessMapper;
    private final VmTypeMapper vmTypeMapper;

    @Override
    public List<Node> getByRegionIds(List<String> regionIds) {
        // TODO: 实现根据区域ID列表查询点位信息的逻辑
        return null;
    }

    /**
     * 分页查询点位信息
     * @param nodePageDTO
     * @return
     */
    @Override
    public PageResult<tbNodePageVO> page(NodePageDTO nodePageDTO) {
        PageHelper.startPage(nodePageDTO.getPageIndex(), nodePageDTO.getPageSize());

        //   一个点位可以投放多个售货机   拿到所有的点位集合数据
        Page<Node> tbNodePage = nodeMapper.page(nodePageDTO);
        log.info("点位数据集合为:{}", tbNodePage);

        if (tbNodePage.isEmpty()) {
            throw new BaseException("没有点位数据");
        }
        //这里拿到的是点位id集合
        List<String> tbNodeIds = tbNodePage.stream()
                .map(Node::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 根据点位ids查询投放的机器数量
        List<Map<String, Object>> vmCountList = vendingMachineMapper.getNodeIds(tbNodeIds);


        //拿到区域id
        List<String> regionIds = tbNodePage.stream()
                .map(Node::getRegionId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        //拿到所有的region对象集合数据
        List<Region> regionList = regionMapper.getByids(regionIds);

        //3.根据tbNodeId分组
        Map<String, List<Node>> listMap = tbNodePage.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(Node::getRegionId));

        //4.封装到输出对象中          这里拿到所有返回前端数据格式:  region
        List<RegionPageVO> regionPageVOList = regionList.stream().map(region -> {
            //区域id
            String id = region.getId();

            //创建对象
            RegionPageVO regionPageVO = new RegionPageVO();
            //将属性拷贝到输出对象中
            BeanUtils.copyProperties(region, regionPageVO);

            List<Node> tbNodes = listMap.getOrDefault(id, new ArrayList<>());//拿到对应id下的集合数据
            //设置nodeList
            regionPageVO.setNodeList(tbNodes);
            regionPageVO.setNodeCount(tbNodes.size());
            return regionPageVO;
        }).collect(Collectors.toList());


        // 拿到商圈所有的id集合
        List<String> businessIds = tbNodePage.stream()
                .map(Node::getBusinessId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        //拿到商圈对象集合
        List<Business> businessList = businessMapper.geyByIds(businessIds);

        List<tbNodePageVO> tbNodePageVOList = tbNodePage.stream()
                .map(tbNode -> {
                    //拿到tbNode的id用于比较
                    String id = tbNode.getId();
                    tbNodePageVO tbNodePageVO = new tbNodePageVO();
                    BeanUtils.copyProperties(tbNode, tbNodePageVO);
                    tbNodePageVO.setRegion(regionPageVOList.stream()
                            .filter(regionPageVO -> regionPageVO.getId().equals(tbNode.getRegionId()))
                            .findFirst()
                            .orElse(null));

                    tbNodePageVO.setBusinessType(businessList.stream()
                            .filter(business -> business.getId().equals(tbNode.getBusinessId()))
                            .findFirst()
                            .orElse(null));

                    tbNodePageVO.setVmCount(vmCountList.stream()
                            .filter(vmCount -> vmCount.get("nodeId").equals(id))
                            .map(vmCount -> vmCount.get("vmCount"))
                            .findFirst()
                            .map(obj -> ((Long) obj).intValue())
                            .orElse(0));
                    return tbNodePageVO;
                }).collect(Collectors.toList());


        long total = tbNodePage.getTotal();  //总条数


        return PageResult.<tbNodePageVO>builder()
                .pageIndex(nodePageDTO.getPageIndex())
                .pageSize(nodePageDTO.getPageSize())
                .totalPage((int) Math.ceil(total / (double) nodePageDTO.getPageSize()))
                .totalCount((int) total)
                .currentPageRecords(tbNodePageVOList)
                .build();
    }

    /**
     * 新增点位
     * @param node
     * @return
     */
    @Override
    public void addNode(Node node) {

        node.setCreateUserId(BaseContext.getCurrentId());
        nodeMapper.addNode(node);
    }

    /**
     * 删除点位
     * @param id
     * @return
     */
    @Override
    public void deleteNode(String id) {

        //判断是否有售货机关联
        int count = vendingMachineMapper.getByNodeId(id);

        if (count > 0) {
            throw new BaseException(MessageConstant.AREA_BE_RELATED_BY_NODE);
        }
        nodeMapper.deleteById(id);
    }

    /**
     * 修改点位
     * @param node
     * @return
     */
    @Override
    public void updateNode(Node node) {

        nodeMapper.updateById(node);
    }

    /**
     * 获取点位详情
     * @param nodeId
     * @return
     */
    @Override
    public List<NodeDetailVO> nodeDetail(String nodeId) {

     List<NodeDetailVO>  nodeDetailVO =  nodeMapper.selectNodeDetail(nodeId);

     return nodeDetailVO;
    }

    /**
     * 点位收藏
     * @return
     */
    @Override
    public List<NodeCollectVO> nodeCollect() {

        List<NodeCollectVO> nodeCollectVO = nodeMapper.nodeCollect();
        return nodeCollectVO;
    }

}
